(function(exports, global) {
	var util = exports;
	util.version = '0.1';

	util.generateImgUrl = function(bytearr) {
		var tbuf = new ArrayBuffer(bytearr.length);
		var tb = new Int8Array(tbuf);
		for (var j = 0; j < bytearr.length; j++) {
			tb[j] = bytearr[j];
		}

		var blob = new Blob([ tbuf ], {
			type : 'application/octet-binary'
		});
		return URL.createObjectURL(blob);
	};

    util.generateAudioUrl = function(bytearr) {
        var tbuf = new ArrayBuffer(bytearr.length);
        var tb = new Int8Array(tbuf);
        for (var j = 0; j < bytearr.length; j++) {
            tb[j] = bytearr[j];
        }

        var blob = new Blob([ tbuf ], {
            type : 'application/octet-binary'
        });
        return URL.createObjectURL(blob);
    };

	util.unPackMsg = function(msg) {
		var content = new Int8Array(msg, 5);
		// var unPackedMsg = util.decode(String.fromCharCode.apply(null,
		// content));
		var unPackedMsg = util.asciiByteArrayToString(content, 1024);
		var len = new Int32Array(msg, 0, 1)[0];
		var type = new Int8Array(msg, 4, 1)[0];
		return {
			type : type,
			content : JSON.parse(unPackedMsg)
		};
	};

	util.packMsg = function(msg, msgType) {
		msg = JSON.stringify(msg);
		msg = util.encode(msg);
		var msgLen = util.stringByteLen(msg);
		var b = new ArrayBuffer(4 + 1);
		var v1 = new Int32Array(b, 0, 1);
		var v2 = new Int8Array(b, 4, 1);
		v1[0] = msgLen;
		v2[0] = msgType;
		pm = new Array(2);
		pm[0] = b;
		pm[1] = msg;

		var blob = new Blob(pm, {
			type : "application/octet-binary"
		});
		return blob;
	};

	util.asciiByteArrayToString = function(byteArr, steplen) {
		var steps = Math.floor(byteArr.length / steplen)
				+ ((byteArr.length % steplen) > 0 ? 1 : 0)
		var begidx = 0;
		var steparr = null;
		var strArr = new Array(steps);
		for (var i = 1; i < steps; i++) {
			steparr = new Int8Array(byteArr.buffer, begidx + 5, steplen);
			strArr[i - 1] = String.fromCharCode.apply(null, steparr);
			begidx += steplen;
		}
		strArr[steps - 1] = String.fromCharCode.apply(null, new Int8Array(
				byteArr.buffer, begidx + 5));
		var str = "";
		for (var j = 0; j < strArr.length; j++) {
			str += strArr[j];
		}
		return util.decode(str);
	};

	util.encode = function(unzipStr) {
		try {
			var zipstr = "";
			var strSpecial = "!\"#$%&'()*+,/:;<=>?[]^`{|}~%";
			var tt = "";
			for (var i = 0; i < unzipStr.length; i++) {
				var chr = unzipStr.charAt(i);
				var c = util.stringToAscii(chr);
				tt += chr + ":" + c + "n";
				if (parseInt("0x" + c) > 0x7f) {
					zipstr += encodeURI(unzipStr.substr(i, 1));
				} else {
					if (chr == " ")
						zipstr += "+";
					else if (strSpecial.indexOf(chr) != -1)
						zipstr += "%" + c.toString(16);
					else
						zipstr += chr;
				}
			}
			return zipstr;
		} catch (err) {

		}
	};

	util.decode = function(zipStr) {
		try {
			var uzipStr = "";
			for (var i = 0; i < zipStr.length; i++) {
				var chr = zipStr.charAt(i);
				if (chr == "+") {
					uzipStr += " ";
				} else if (chr == "%") {
					var asc = zipStr.substring(i + 1, i + 3);
					if (parseInt("0x" + asc) > 0x7f) {
						uzipStr += decodeURI("%" + asc.toString()
								+ zipStr.substring(i + 3, i + 9).toString());
						i += 8;
					} else {
						uzipStr += util.asciiToString(parseInt("0x" + asc));
						i += 2;
					}
				} else {
					uzipStr += chr;
				}
			}
			return uzipStr;
		} catch (err) {

		}
	};

	util.stringToAscii = function(str) {
		return str.charCodeAt(0).toString(16);
	};

	util.asciiToString = function(asccode) {
		return String.fromCharCode(asccode);
	};

	util.stringByteLen = function(str) {
		return str.replace(/[^x00-xFF]/g, '**').length;
	};

})(this.wsutil = {}, this);